home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
fdimg
/
—‹Œêsrc.lzh
/
line.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-01-27
|
24KB
|
1,132 lines
#include "3DDEF.H"
#include "GLOBAL.H"
#include "FORWARD.H"
#include "XCODE.H"
/* 行管理 */
/* カレントウインドウの最上行を得る */
UNIT *
line_my_top()
{
register UNIT *p;
p = SCREEN[CWY0];
if ((int)p & (int)0xffffff00) {
return(p);
}
return(SCREEN[CWY0]);
}
/* カレントウインドウの n 行目を得る */
UNIT *
line_my_screen(int n)
{
return(SCREEN[CWY0 + n]);
}
/* w 番ウインドウの n 行目を得る */
UNIT *
line_x_screen(int w,int n)
{
return(SCREEN[WDATA[w].WY0 + n]);
}
/* up の begin_byte から、tb バイトだけたどる */
/* 新しい行へのポインタを返す */
/* new_byte_count にその行の何バイト目なのかを返す */
/* movel != NIL なら、*movel に、実際に移動した行数(+-)を返す */
UNIT *
line_trace_byte(UNIT *up, int begin_byte, int tb, int *new_byte_count, int *movel)
{
register UNIT *wp;
register int len,counter = 0;
tb += begin_byte;
wp = up;
line_seigyou();
if (tb >= 0) { /* 後ろへトレース */
while(1) {
len = (wp->LENGTH);
if (len >= tb) {
*new_byte_count = tb;
break;
}
tb -= len;
#if 0
if (!(wp->ATO)) {
wp->ATO = TAIL;
*new_byte_count = wp->LENGTH; /* 最後の行の右端 */
break;
}
#endif
if ((wp = wp->ATO) == TAIL) {
wp = TAIL->MAE;
*new_byte_count = wp->LENGTH; /* 最後の行の右端 */
break;
}
counter++;
}
} else { /* 前へトレース */
tb = -tb;
while(1) {
len = wp->LENGTH;
if (len >= tb) {
*new_byte_count = len - tb;
break;
}
tb -= len;
if ((wp = wp->MAE) == HEAD) {
wp = HEAD->ATO;
*new_byte_count = 0; /* 最初の行の左端 */
break;
}
counter--;
}
}
if (movel) {
*movel = counter;
}
return(wp);
}
/* up から tl 行たどる */
/* 頭もしくは尾に達したら 頭行もしくは尾行を返す */
/* movel != NIL なら、*movel に、実際に移動した行数(+-)を返す */
UNIT *
line_trace(UNIT *up, int tl, int *movel)
{
register UNIT *wp;
register int i,counter=0;
wp = up;
if (tl) { /* tl が0でないなら */
if (tl > 0) {
for(i=0;i<tl;i++,counter++) {
if (wp == NULL) {
break;
}
if ((wp = wp->ATO) == TAIL) {
wp = TAIL->MAE; /* 戻る */
break;
}
if (wp->ATO == NULL) {
wp = wp->MAE;
counter--;
break;
}
}
} else {
tl = -tl;
for(i=0;i<tl;i++,counter--) {
if (wp == NULL) {
break;
}
if ((wp = wp->MAE) == HEAD) {
wp = HEAD->ATO; /* 戻る */
break;
}
if (wp->MAE == NULL) {
wp = wp->ATO;
counter--;
break;
}
}
}
}
if (movel) {
*movel = counter;
}
return(wp);
}
/* up の指す行の行頭に s1+s2 を挿入し、次々に送って行く。最後まで勝負する */
/* エコーする */
void
line_arrange(UNIT *up,STR s1,STR s2)
{
UBYTE seed[strlen(s1)+strlen(s2)+VERY_LONG_LINE+1];
UBYTE w0[VERY_LONG_LINE],retw[VERY_LONG_LINE];
UNIT *wp,*np;
register int restl;
int flag;
strcpy(seed,s1);
strcat(seed,s2); /* まずは挿入部分 */
#if 0
if (!(restl = strlen(seed))) { /* 空なら終わり */
return;
}
#endif
if (up == NIL) {
error("バグが発生しました");
return;
/* ctrl_x_ctrl_c();*/
}
line_make_bag_list(seed);
/*printf("seed = %s",seed);binkey();*/
while(1) {
wp = line_get_from_bag();
if (BAG_HEAD == NIL) { /* 最後の行なら抜ける */
break;
}
line_insert1_mae_echo(wp,up); /* 1行挿入 */
}
if ((up == TAIL) && wp) {
line_insert1_mae_echo(wp,up); /* 最後の一行を挿入して終り */
return;
}
np = up;
line_get_body(seed,wp); /* 最後の一行のデータを取って来る */
while(strlen(seed)) {
if (np == TAIL) { /* 最後に達した */
wp = line_get_free_and_store(seed);
line_append1_echo(wp);
/*window0();printf("1break");binkey();*/
break;
}
line_get_body(w0,np); /* w0 は常にその次の行の中身を示す */
/*window0();printf("[%s][%s]",seed,w0);binkey();*/
flag = cut_2line_link_check(seed,w0,retw,seed,CURRENT_JIZUME);
if (!flag) { /* 出入りが無かった */
line_empty_bag((STR) NIL);
wp = line_get_free_and_store(retw);
line_insert1_mae_echo(wp,np); /* 最後の一行を挿入して終り */
/*window0();printf("2break");binkey();*/
break;
}
if (flag < 0) { /* 前に送られた */
if (!strlen(seed) && (etc_last(retw) != CR)) { /* 短過ぎた */
/* もしくはちょうど */
/*window0();printf("TOO SHORT[%s][%s]",seed,retw);binkey();*/
strcpy(seed,retw); /* 戻す */
/* np -> w0 ですでに追加してある! */
np = np->ATO;
line_delete1_echo_after_bag(np->MAE);
if (np == TAIL) { /* もう後はないから1行作って終わり */
/*window0();printf(seed);binkey();*/
wp = line_get_free_and_store(seed);
/* line_delete1_echo_after_bag(TAIL->MAE);*/
line_append1_echo(wp);
/*window0();printf("3break");binkey();*/
break;
}
continue;
#if 0
line_cat_body(seed,np); /* その次の行を取って来る */
window0();printf("TOO SHORT2[%s]",seed);binkey();
/* strcat(seed,w0);*/
np = np->ATO;
line_delete1_echo_after_bag(np->MAE);
/* 一行削除:ただしその行は袋の後ろにあること */
continue;
#endif
} else { /* retw で1行作って良い */
line_store_and_echo(np,retw);
np = np->ATO;
continue;
}
}
if (flag > 0) { /* 後ろに送った */
/* retw で1行作って良い */
wp = line_get_free_and_store(retw);
/* line_store_and_echo(np,retw);*/
line_insert1_mae_echo(wp,np); /* 挿入する */
np = np->ATO;
/*window0();printf(seed);binkey();*/
seed[strlen(seed)-strlen(w0)] = EOS;
/* w0 は変わらず */
continue;
}
}
return;
}
/* up の指す行から、次々に整行して行く。最後まで勝負する */
/* エコーする */
void
line_arrange_all(UNIT *up)
{
register UNIT *wp,*wp0,*wp1;
UBYTE w0[VERY_LONG_LINE*2],w1[VERY_LONG_LINE];
if ((wp0 = up) == TAIL) { /* エラーやがな */
return;
}
line_get_body(w0,wp0);
wp1 = wp0->ATO;
while(1) {
if (wp1 != TAIL) { /* 最後の行でないなら */
line_get_body(w1,wp1); /* 行のデータを取って来る */
strcat(w0,w1);
wp = wp1->ATO;
/*printf("[[%x:%x]]\n",wp1,wp);binkey();*/
line_set_free(wp1); /* wp1 を捨てる */
wp1 = wp;
}
while(1) {
cut_line(w0,w1,w0,CURRENT_JIZUME); /* カットしてみる */
if (*w0) { /* 1行取れた */
wp = line_get_free_and_store(w1);
/*printf("(取れた%d:%d)",strlen(w1),kkk);binkey();*/
line_insert1_mae(wp,wp0);
} else {
/*printf("(取れなかった%d:%d)",strlen(w1),kkk);binkey();*/
strcpy(w0,w1); /* 戻す */
/*window0();printf("4break");binkey();*/
break;
}
}
if (wp1 == TAIL) {
line_store(wp0,w0);
wp0->ATO = TAIL;
TAIL->MAE = wp0;
/*window0();printf("5break");binkey();*/
break;
}
}
}
void
line_to_bag(STR s)
{
STR b;
UBYTE bag_temp_work[VERY_LONG_LINE];
int l;
if ((BAG_LENGTH + (l = strlen(s))) > BAG_LIMIT) {
line_arrange(SCREEN[CWY1]->ATO,s,BAG);
line_empty_bag((STR) NIL); /* 袋を空にする */
} else {
strcpy(BAG0,s);
strcat(BAG0,BAG);
b = BAG;
BAG = BAG0;
BAG0 = b;
BAG_LENGTH += l;
}
}
void
line_seigyou()
{
if (SCREEN[CWY1] && BAG_LENGTH) {
under_print((STR) "整行中・・・");
if (SCREEN[CWY1] == TAIL) error("6666");
if (SCREEN[CWY1]->ATO == NIL) error("7777");
line_arrange(SCREEN[CWY1]->ATO,(UBYTE *)"\0",BAG);/* ,,, */
line_empty_bag((STR) NIL); /* 袋を空にする */
under_blanc();
}
}
/* s に袋の中身を転送し、袋を空にする */
/* s が NIL なら転送しない */
void
line_empty_bag(STR s)
{
if (!BAG_LENGTH) { /* 袋は空である */
if (s) {
*s = EOS;
}
} else { /* 袋は空ではない */
if (s) {
strcpy(s,BAG);
}
}
*BAG_CONTENT0 = *BAG_CONTENT1 = EOS;
BAG = BAG_CONTENT0;
BAG0 = BAG_CONTENT1;
while(BAG_HEAD) {
UNIT *p;
p = BAG_HEAD->ATO;
line_set_free(BAG_HEAD);
BAG_HEAD = p;
}
BAG_LENGTH = 0; /* 袋の初期化 */
BAG_HEAD = BAG_TAIL = NIL; /* bag の頭、尻尾へのポインタを無効化 */
}
/* 一行削除:ただしその行は袋の後ろにあること */
/* エコーしない */
void
line_delete1(UNIT *up)
{
line_deleten(up->MAE,up->ATO); /* 二つの行の間を削除する */
}
/* 一行削除:ただしその行は袋の後ろにあるか、もしくは整行済みであること */
/* エコーする */
void
line_delete1_echo_after_bag(UNIT *up)
{
line_deleten_echo(up->MAE,up->ATO); /* 二つの行の間を削除する */
}
void
line_connect(UNIT *maep,UNIT *atop)
{
maep->ATO = atop; /* 前の行の後ろを、後ろの行にする */
atop->MAE = maep; /* 後ろの行の前を、前の行にする */
}
/* maep < 削除される < atop */
/* 与えられた行は削除されない */
void
line_deleten_echo(UNIT *maep,UNIT *atop)
{
UNIT *wp_mae,*wp_ato,*wp,*wp0;
wp_mae = maep;
wp_ato = atop;
wp = wp_mae->ATO;
/* atop を wp_mae に手繰る */
while((wp_mae = wp) != atop) {
if (wp_ato) { /* 尾に当たれば自動的に止まる */
disp_replace(wp_mae,wp0 = wp_ato); /* 前を後で置き換える */
wp = wp_mae->ATO;
wp_ato = wp_ato->ATO;
line_set_free_with_ext(wp_mae);
} else {
/* disp_replace(wp_mae,wp0 = wp_ato); 前を後で置き換える */
break;
}
}
if (wp_ato) {
disp_replace_after(wp0,wp0->ATO);
}
line_connect(maep,atop); /* 二つの行を接続する */
}
#if 1
/* SCREEN[] から maep < 削除される < atop */
/* 与えられた行は削除されない */
void
line_deleten_SCREEN(UNIT *maep,UNIT *atop)
{
UNIT *wp_mae,*wp_ato,*wp,*wp0;
UBYTE string[VERY_LONG_LINE];
line_connect(maep,atop); /* 二つの行を接続する */
return;
wp_mae = maep;
wp_ato = atop;
wp = wp_mae->ATO;
/* atop を wp_mae に手繰る */
while((wp_mae = wp) != atop) { /* atop は削除されないから、そこに達したら終了 */
if (wp_ato) { /* 尾に当たれば自動的に止まる */
disp_replace_SCREEN(wp_mae,wp0 = wp_ato); /* 前を後で置き換える */
wp = wp_mae->ATO;
wp_ato = wp_ato->ATO;
line_set_free_with_ext(wp_mae);
} else {
/* disp_replace_SCREEN(wp_mae,wp0 = wp_ato); 前を後で置き換える */
break;
}
}
if (wp_ato) {
disp_replace_after_SCREEN(wp0,wp0->ATO);
}
/* disp_replace_after(atop->MAE,atop);*/
/* line_set_free_with_ext(atop->MAE);*/
line_connect(maep,atop); /* 二つの行を接続する */
}
#endif
/* maep < 削除される < atop */
/* 与えられた行は削除されない */
/* エコーしない */
void
line_deleten(UNIT *maep,UNIT *atop)
{
register UNIT *wp_mae,*wp;
wp_mae = maep->ATO;
/*printf("[%x:%x]",maep,atop);binkey();*/
do {
wp = wp_mae->ATO;
line_set_free_with_ext(wp_mae);
} while((wp_mae = wp) != atop);
line_connect(maep,atop); /* 二つの行を接続する */
}
/* seed をカッティングして袋のリストにする */
void
line_make_bag_list(STR seed)
{
UBYTE s[VERY_LONG_LINE],l[VERY_LONG_LINE],w[VERY_LONG_LINE];
UNIT *p;
UINT c,jizume;
FILE *fp;
*s = EOS; /* 前からの繰り越しはなし */
jizume = CURRENT_JIZUME;
do {
if (!*s) { /* s がヌルなら適当な長さだけ読み出す */
strncpy(s,seed,jizume + 4);
s[jizume + 4] = EOS;
seed += strlen(s);
}
while(1) {
if (string_disp_len(s) > (jizume+4)) { /* 禁則はみだしがあるので長め */
break;
}
strncpy(l,seed,jizume + 4);
l[jizume + 4] = EOS;
seed += strlen(l); /* 適当な長さだけ読み出す */
strcat(s,l); /* 前からの繰り越しの後に加える */
if (!*seed) break;
}
if (!*s) { /* 前部使った */
break;
}
cut_line(s,w,s,jizume);
p = line_append_bag_list(w);
if (p == NIL) { /* フリーラインが無い! */
etc_inp_y((STR)"メモリが足りません。中断します [Y]?");
line_empty_bag(NULL);
return;
}
} while(*seed || *s);
}
UNIT *
line_append_bag_list(UBYTE *s)
{
UNIT *p;
if (!(p = line_get_free_and_store(s))) return(NIL);
if (BAG_HEAD) { /* 袋リストがある */
BAG_TAIL->ATO = p; /* 最後の次が手持ちになる */
p->MAE = BAG_TAIL; /* 手持ちの前は最後 */
p->ATO = NIL; /* 新しい最後は NIL を指す */
BAG_TAIL = p; /* 新しい最後を指す */
} else { /* フリーラインがない */
BAG_HEAD = BAG_TAIL = p;
p->MAE = p->ATO = NIL;
}
return(p);
}
/* 袋リストの頭から順番に1つづつ外して行く */
UNIT *
line_get_from_bag()
{
UNIT *wp;
if (wp = BAG_HEAD) {
BAG_HEAD = BAG_HEAD->ATO;
} /* HEAD が NIL なら TAIL は無効だからこれでいいのだ */
return(wp);
}
/* 文字列にユニットの中身を追加する */
/* 追加した長さを返す */
int
line_cat_body(STR l,UNIT *p)
{
register int i;
strcat(l,p->BODY);
i = line_length(p);
while (p = p->EXT) {
strcat(l,p->BODY);
}
return(i);
}
/* テキストの末尾に1行アペンドする */
/* エコーしない */
void
line_append1(UNIT *unit_pointer)
{
line_insert1_mae(unit_pointer,TAIL);
}
/* テキストの末尾に1行アペンドする */
/* エコーする */
void
line_append1_echo(UNIT *unit_pointer)
{
line_insert1_mae_echo(unit_pointer,TAIL);
}
/* text_line_pointer の後ろに1行挿入する */
/* エコーする */
void
line_insert1_after(UNIT *insert_unit_pointer,UNIT *text_line_pointer)
{
UNIT *n;
if (text_line_pointer == TAIL) {
error("バグです。TAIL の後ろに挿入しようとした");
} else {
line_insert1_mae_echo(insert_unit_pointer,text_line_pointer->ATO);
}
}
/* text_line_pointer の前に1行挿入する */
/* エコーする */
void
line_insert1_mae_echo(UNIT *insert_unit_pointer,UNIT *text_line_pointer)/* ,,,, */
{
UNIT *b;
line_insert1_mae(insert_unit_pointer,text_line_pointer);
disp_check_1line_insert(insert_unit_pointer,text_line_pointer);
/* 必要ならば画面にエコーする */
}
/* text_line_pointer の前に1行挿入する */
/* エコーしない */
void
line_insert1_mae(UNIT *insert_unit_pointer,UNIT *text_line_pointer)
{
UNIT *b;
if (!insert_unit_pointer) { /* メモリの限界に来ている */
etc_beep();
under_print0((STR)"メモリ不足:文章を保存して、終了して下さい [Y]? ");
etc_wait_y();
insert_unit_pointer = &AXE;
}
if (text_line_pointer == HEAD) {
error("バグです。HEAD の前に挿入しようとした");
} else {
b = text_line_pointer->MAE; /* 前の行へのポインタ */
text_line_pointer->MAE = b->ATO = insert_unit_pointer;
insert_unit_pointer->ATO = text_line_pointer;
/* 後ろのリンク */
insert_unit_pointer->MAE = b; /* 前のリンク */
}
}
/* フリーラインを新しく得て、与えられた文字列を格納する */
/* 1ユニットで格納しきれない時は自動的に拡張する */
UNIT *
line_get_free_and_store_with_echo(STR s)
{
UNIT *p,*p0,*q;
int l,lmin;
if (p = line_get_free()) {
if (line_store_and_echo(p,s)) {
return(p);
} else {
line_set_free(p);
}
}
return(NIL); /* 得られなかった */
}
/* フリーラインを新しく得て、与えられた文字列を格納する */
/* 1ユニットで格納しきれない時は自動的に拡張する */
UNIT *
line_get_free_and_store(STR s)
{
UNIT *p,*p0,*q;
int l,lmin;
if (p = line_get_free()) {
if (line_store(p,s)) {
return(p);
} else {
line_set_free(p);
}
} else {
return(NIL); /* 1行も得られなかった */
}
}
UNIT *
line_get_free_and_store_ck(STR s)
{
register UNIT *p;
if (!(p = line_get_free_and_store(s))) {
error("おそらくメモリ不足です。新しい行を確保出来ません");
}
return(p);
}
/* 指定されたユニット(拡張可)に与えられた文字列を格納する */
/* 格納しきれない時は自動的に拡張する、余った場合も自動的に開放する */
/* 画面にエコーする */
UNIT *
line_store_and_echo(UNIT *up, STR s)
{
UNIT *wp;
if (up == TAIL) {
wp = line_get_free_and_store(s);
line_append1_echo(wp);
} else {
line_store(up,s);
disp_check_1line_echo(up);
}
}
/* 指定されたユニット(拡張可)に与えられた文字列を格納する */
/* 格納しきれない時は自動的に拡張する、余った場合も自動的に開放する */
/* エコーしない */
UNIT *
line_store(UNIT *up, STR s)
{
UNIT *p,*q;
int l,lmin;
up->LENGTH = l = strlen(s);
if (l < BODYSIZE-1) {
strcpy(up->BODY,s);
if (up->EXT) {
line_set_free_with_ext(up->EXT);
up->EXT = NIL;
}
return(up);
}
strncpy(up->BODY,s,lmin = BODYSIZE-1); /* 最初のユニット */
s += lmin;
p = up;
while ((l -= lmin) > 0) { /* long line */
p->BODY[BODYSIZE-1] = EOS; /* EOS を追加 */
if (!(q = p->EXT)) { /* 拡張が必要なのに今は持ってない */
if (q = line_get_free()) { /* 取れた */
p->EXT = q;
} else { /* 取れなかった */
line_set_free_with_ext(up->EXT);
return(NIL);
}
}
lmin = min(BODYSIZE-1,l);
strncpy(q->BODY,s,lmin);
(q->BODY)[lmin] = EOS;
s += lmin;
p = q;
}
if (p->EXT) {
line_set_free_with_ext(p->EXT);
p->EXT = NIL;
}
return(up);
}
void
line_get_body(STR s,UNIT *p)
{
if (p) {
strcpy(s,p->BODY);
while (p = p->EXT) {
strcat(s,p->BODY);
}
}
}
/* エラーなら 0 を返す */
int
line_make_line(int number_of_line)
{
int i;
UNIT *ptr;
if (number_of_line) {
if (ptr = line_get_memory(number_of_line)) {
/* フリーラインに追加していく */
for(i = 0;i < number_of_line;i++) {
line_set_free(ptr++);
}
} else {
return(FALSE); /* 必要な領域を確保できなかった */
}
}
return(TRUE);
}
/* メモリの確保 */
UNIT *
line_get_memory(int number_of_line)
{
int s;
s = number_of_line*sizeof(UNIT);
if (s % 1024) {
s = s/1024+1;
} else {
s = s/1024;
}
bldmem(s);
return((UNIT *)calloc(number_of_line,sizeof(UNIT)));
/* calloc は0で初期化する */
}
/* フリーなユニットへのポインタを返す */
/* フリーリストから外す */
/* 頭から外していく */
/* ない場合は NIL を返す */
UNIT *
line_get_free()
{
UNIT *p;
/*
if (sysflag) {
int *BUS = 0;
error("###");
*BUS = 0;
return;
}
sysflag = 1;
*/
if (LINE_SHORT) {
return(&AXE);
}
/* フリーラインがない */ /* 作れない */
if ((!FREE_LINE_COUNTER) && (!line_make_line(128))) {
LINE_SHORT = 1;
under_print0((STR)"重大な事態。メモリ不足:大事な文章を保存して、終了して下さい [Y]? ");
etc_wait_y();
return(&AXE);
/* return(NIL);*/
}
FREE_LINE_COUNTER--; /* フリーラインがある */
p = FREE_HEAD;
if (FREE_HEAD = FREE_HEAD->ATO) { /* 次がある(最後ではなかった) */
FREE_HEAD->MAE = NIL; /* 新しい先頭行の前は NIL */
} else { /* 最後の行だった */
FREE_TAIL = NIL; /* 尻尾に NIL を指させる */
}
p->MAE = NIL;
p->ATO = NIL;
p->EXT = NIL;
p->LENGTH = 0;
p->BODY[0] = EOS;
return(p);
}
/* フリーなユニットにする */
void
line_set_free(UNIT *unit_pointer)
{
if (FREE_LINE_COUNTER) { /* フリーラインがある */
FREE_TAIL->ATO = unit_pointer; /* 最後の次が手持ち */
unit_pointer->MAE = FREE_TAIL; /* 手持ちの前は最後 */
unit_pointer->ATO = NIL; /* 新しい最後は NIL を指す */
unit_pointer->EXT = NIL;
FREE_TAIL = unit_pointer; /* 新しい最後を指す */
} else { /* フリーラインがない */
FREE_HEAD = FREE_TAIL = unit_pointer;
unit_pointer->MAE = unit_pointer->ATO = NIL;
}
FREE_LINE_COUNTER++;
}
/* 拡張を含めて開放する */
/* 再帰を使ってランララン */
void
line_set_free_with_ext(UNIT *unit_pointer)
{
UNIT *xp;
if (xp = unit_pointer->EXT) {
line_set_free_with_ext(xp);
}
line_set_free(unit_pointer);
}
/* 現在行の n 文字目の文字コードを1バイト取って来る */
UBYTE
line_cl_1byte(int n)
{
return(*(line_skip_xcode(CL_DATA + ANALYZE[n].BPOS)));
}
/* 現在行の n 文字目の文字コードを1文字取って来る */
UINT c;
line_cl_code(int n)
{
register STR p;
register UINT c;
p = line_skip_xcode(CL_DATA + ANALYZE[n].BPOS);
if (iskanji(c = *p++)) {
c = (c<<8) | *p;
}
return(c);
}
/* カーソルの下の文字コードを1バイト取って来る */
UBYTE
line_cpx_1byte()
{
return(*(line_skip_xcode(CL_DATA + ANALYZE[CPX].BPOS)));
}
/* カーソルの下の文字コードを取って来る */
UINT
line_cpx_code()
{
register STR wp;
UINT c;
wp = line_skip_xcode(&CL_DATA[ANALYZE[CPX].BPOS]); /* 実体のアドレスを得る */
if (etc_char_byte_haba(wp) <= 1) {
return(*wp);
} else {
c = *wp++;
return(c << 8 | *wp);
}
}
/* 拡張コードをスキップする */
/* ポインタを返す */
STR
line_skip_xcode(STR p)
{
register UINT c1;
while(*p == XCODE_UP) {
c1 = *++p;
p++;
/* c1 を見て、ルビならさらに進める */
if ((XCODE_RB10 <= c1) && (c1 <= XCODE_RB2)) { /* ルビだ */
p += 2;
if (c1 == XCODE_RB2) {
p += 2;
}
}
}
return(p);
}
/* マークコードをスキップする */
/* ポインタを返す */
STR
line_skip_mark(STR p)
{
register UINT c1;
while(*p == XCODE_UP) {
if ((XCODE_SYSMARK <= p[1]) && (p[1] <= XCODE_MARKLAST)) { /* マークだ */
p += 2;
} else {
return(p);
}
}
}
#if 0
/* 文字列の最初の1文字が占めるバイト数を返す(拡張コードも含めたバイト数) */
UINT
line_cxp_char_byte(STR p)
{
register int i = 0;
while(p[i] == XCODE_UP) {
i += 2;
}
return(i + etc_char_byte_haba(p));
}
#endif
/* CL_DATA[bc] から始めて、次の文字までのバイト数を返す */
/* *xc から表示しているとして、*xc を更新する */
int
line_touch_next_char(int bc,int *xc)
{
return(line_touch_next_char_x(CL_DATA,bc,xc));
}
/* p[bc] から始めて、次の文字までのバイト数を返す */
/* *xc から表示しているとして、*xc を更新する */
/* 実体を越える */
int
line_touch_next_char_x(STR p,int bc,int *xc)
{
register UBYTE c;
register UWORD w;
if ((c = p[bc]) < (UBYTE)'\x20') {
switch(c) {
case EOS:
return(bc);
case TAB: /* TAB 0-7 -> 8, 8-15 -> 16... */
w = *xc + TAB_LENGTH;
w -= (w % TAB_LENGTH);
*xc = min(w,CURRENT_JIZUME);
/* *xc = w - (w % TAB_LENGTH);*/
return(bc + 1);
case CR: /* 改行 */
(*xc) += 2;
return(bc + 1);
default: /* 普通のコントロールコード */
(*xc) += 2;
return(bc + 1);
}
}
if (c == XCODE_UP) { /* 拡張コード */
switch(p[bc+1]) { /* 次の1バイトが */
case XCODE_MARK+0:
case XCODE_MARK+1:
case XCODE_MARK+2:
case XCODE_MARK+3:
case XCODE_MARK+4:
case XCODE_MARK+5:
case XCODE_MARK+6:
case XCODE_MARK+7:
case XCODE_MARK+8:
case XCODE_MARK+9: /* マーク 0x20 - 0x29 */
case XCODE_MARK+10:
case XCODE_MARK+11:
case XCODE_MARK+12:
case XCODE_MARK+13:
case XCODE_MARK+14:
case XCODE_MARK+15:
case XCODE_SYSMARK+0: /* システムマーク */
case XCODE_SYSMARK+1:
case XCODE_SYSMARK+2:
case XCODE_SYSMARK+3:
case XCODE_SYSMARK+4:
case XCODE_SYSMARK+5:
case XCODE_SYSMARK+6:
case XCODE_SYSMARK+7:
case XCODE_SYSMARK+8:
case XCODE_SYSMARK+9:
case XCODE_SYSMARK+10:
case XCODE_SYSMARK+11:
case XCODE_SYSMARK+12:
case XCODE_SYSMARK+13:
case XCODE_SYSMARK+14:
case XCODE_SYSMARK+15:
case XCODE_UL: /* 下線 */
return(line_touch_next_char_x(p,bc+2,xc));
case XCODE_RB10: /* 予約:1文字真ん中ルビ */
case XCODE_RB1: /* 1文字ルビ */
case XCODE_RB1L: /* 1文字ルビ左(全角用) */
case XCODE_RB1R: /* 1文字ルビ右(全角用) */
return(line_touch_next_char_x(p,bc+4,xc));
case XCODE_RB2: /* 2文字ルビ */
return(line_touch_next_char_x(p,bc+6,xc));
}
}
if (iskanji(c)) { /* 普通の全角 */
(*xc) += 2;
return(bc + 2);
}
if (buff_ishan2byte(c)) {
(*xc)++;
return(bc + 2);
}
(*xc)++;
return(bc + 1);
}
/* */
/* void */
line_cl_cl()
{
register UNIT *p = CL;
if (p) {
strcpy(CL_DATA,p->BODY);
while (p = p->EXT) {
strcat(CL_DATA,p->BODY);
}
}
}
/* s に CL_DATA から n バイトコピーする */
void
line_cl_strncpy(STR s,int n)
{
strncpy(s,CL_DATA,n);
}
/* s に CL_DATA の n バイト目からのデータを追加する */
void
line_cl_strcat(STR s,int n)
{
strcat(s,&CL_DATA[n]);
}
/* s に CL_DATA の n バイト目からの l バイトのデータを追加する */
void
line_cl_strncat(STR s,int n,int l)
{
strncat(s,&CL_DATA[n],l);
}
/* maep <= 削除される <= atop */
/* 与えられた行は削除されない */
/* エコーしない */
void
line_deleten_list(UNIT *maep,UNIT *atop)
{
register UNIT *wp;
/*window0();*/
if (maep) {
while(1) {
wp = maep->ATO;
/*printf("[%x]\n",maep);binkey();*/
line_set_free_with_ext(maep);
if (maep == atop) {
break;
}
maep = wp;
}
}
}
int
line_length(UNIT *p)
{
return(p->LENGTH);
}
/* CL_DATA の前置している属性までさかのぼる */
/* 解析済み */
int
line_remove_attribute(int bp1)
{
register int i,j;
j = i = 0;
while(bp1 >= ANALYZE[i].BPOS) {
j = i++;
}
if (bp1 == ANALYZE[i].BPOS) {
return(bp1);
} else {
return(ANALYZE[j].BPOS);
}
}